package com.ihg.hiex.admin.service.session.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.CollectionUtils;
import com.ihg.hiex.admin.dao.session.SessionDao;
import com.ihg.hiex.admin.dao.session.SessionReportDao;
import com.ihg.hiex.admin.dao.session.SessionReportWritingDao;
import com.ihg.hiex.admin.entity.upload.OnlineReport;
import com.ihg.hiex.admin.service.session.SessionReportService;
import com.ihg.hiex.entity.session.Session;
import com.ihg.hiex.entity.session.SessionAttribute;
import com.ihg.hiex.entity.session.after.ReportGenerateStatus;
import com.ihg.hiex.entity.session.after.ReportSendStatus;
import com.ihg.hiex.entity.session.after.SessionReport;
import com.ihg.hiex.entity.session.during.SessionCalibration;
import com.ihg.hiex.entity.session.during.report.SessionReportWriting;
import com.ihg.hiex.entity.user.Delegate;

/**
 * 
 * @author dan
 *
 */
@Service("sessionReportService")
public class SessionReportServiceImpl implements SessionReportService{
    
    @Dao
    private SessionReportDao sessionReportDao;
    
    @Dao
    private SessionDao sessionDao;
    
    @Dao
    private SessionReportWritingDao sessionReportWritingDao;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;

    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#list(com.ihg.hiex.entity.session.Session)
     */
    public Map<String, SessionReport> list(Session session) {
        List<SessionReport> sessionReports = sessionReportDao.list(session);
        return CollectionUtils.constructMapValue(sessionReports, "delegate.id");
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#list(com.ihg.hiex.entity.session.Session, java.lang.String)
     */
    public List<SessionReport> list(Session session, String reportName) {
        
        List<SessionReportWriting> reportWritings = sessionReportWritingDao.list(session);
        if(StringUtils.equalsIgnoreCase(reportName, "managerReport")) {
            List<SessionReport> reports = sessionReportDao.listManagerReport(session, ReportGenerateStatus.UNGENERATED);
            return this.generateReport(reports, reportWritings);
        } else if(StringUtils.equalsIgnoreCase(reportName, "pplReport")) {
            List<SessionReport> reports = sessionReportDao.listPplReport(session, ReportGenerateStatus.UNGENERATED);
            return this.generateReport(reports, reportWritings);
        } else {
            return sessionReportDao.listDelegateReport(session, ReportGenerateStatus.UNGENERATED);
        }
    }
    
    private List<SessionReport> generateReport(List<SessionReport> reports, List<SessionReportWriting> reportWritings) {
        
        List<SessionReport> result = new ArrayList<SessionReport>();
        for(SessionReport report : reports) {
            for(SessionReportWriting reportWriting : reportWritings) {
                if(report.getSession().getId().equals(reportWriting.getSessionCalibration().getSession().getId()) &&
                   report.getDelegate().getId().equals(reportWriting.getSessionCalibration().getDelegate().getId())) {
                    result.add(report);
                }
            }
        }
        
        return result;
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#listBySendStatus(com.ihg.hiex.entity.session.Session, java.lang.String)
     */
    public List<SessionReport> listBySendStatus(Session session, String statusName) {
        if(StringUtils.equalsIgnoreCase(statusName, "delegate")) {
            return sessionReportDao.listSendToDelegateReport(session, ReportGenerateStatus.GENERATED, ReportSendStatus.UNSENT);
        } else {
            return sessionReportDao.listSendToManagerReport(session, ReportGenerateStatus.GENERATED, ReportSendStatus.UNSENT);
        }
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#loadReportWriting(com.ihg.hiex.entity.session.during.SessionCalibration)
     */
    public SessionReportWriting loadReportWriting(SessionCalibration sessionCalibration) {
        return sessionReportWritingDao.load(sessionCalibration);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#listReportWriting(java.util.List)
     */
    public Map<String, SessionReportWriting> listReportWriting(List<SessionCalibration> sessionCalibrations) {
        List<SessionReportWriting> reportWritings = sessionReportWritingDao.list(sessionCalibrations);
        return CollectionUtils.constructMapValue(reportWritings, "sessionCalibration.id");
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#load(com.ihg.hiex.entity.session.Session, com.ihg.hiex.entity.user.Delegate)
     */
    public SessionReport load(Session session, Delegate delegate) {
        return sessionReportDao.load(session, delegate);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#load(com.ihg.hiex.entity.user.Delegate)
     */
    public SessionReport load(Delegate delegate) {
        return sessionReportDao.load(delegate);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#reportUpload(com.ihg.hiex.entity.session.Session, java.util.List, java.lang.Long)
     */
    public void reportUpload(Session session, List<OnlineReport> onlineReports, Long operator) {
        
        for(OnlineReport onlineReport : onlineReports) {
            // load delegate
            Delegate delegate = genericDaoSupport.load(Delegate.class, onlineReport.getDelegateId());
            
            // load sessionReport
            SessionReport sessionReport = sessionReportDao.load(session, delegate);
            
            if(sessionReport == null) {
                sessionReport = new SessionReport(session, delegate, onlineReport.getWaveReport(), onlineReport.getWaveDelegateReport(), onlineReport.getSwiftReport(), operator);
                genericDaoSupport.save(sessionReport);
            } else {
                genericDaoSupport.update(sessionReport.editReport(onlineReport.getWaveReport(), onlineReport.getSwiftReport(), delegate.getId()));
            }
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#reportUpload(com.ihg.hiex.entity.session.Session, com.ihg.hiex.entity.user.Delegate, java.lang.String, java.lang.String, java.lang.Long)
     */
    public void reportUpload(Session session, Delegate delegate, String reportUrl, String reportType, Long operator) {
        // load sessionReport
        SessionReport sessionReport = sessionReportDao.load(session, delegate);
        
        if(sessionReport == null) {
            sessionReport = new SessionReport(session, delegate, reportUrl, operator, reportType);
            genericDaoSupport.save(sessionReport);
        } else {
            genericDaoSupport.update(sessionReport.editReport(reportUrl, operator, reportType));
        }
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#dataUpload(com.ihg.hiex.entity.session.Session, java.lang.String, java.lang.String)
     */
    public void dataUpload(Session session, String waveData, String swiftData) {
        // save or update wave data url
        SessionAttribute waveAttr = sessionDao.loadSessionAttribute(session, "wave-data");
        if(waveAttr == null) {
            waveAttr = new SessionAttribute(session, "wave-data", waveData);
            genericDaoSupport.save(waveAttr);
        } else {
            genericDaoSupport.update(waveAttr.edit(waveData));
        }
        
        // save or update swift data url
        SessionAttribute swiftAttr = sessionDao.loadSessionAttribute(session, "swift-data");
        if(swiftAttr == null) {
            swiftAttr = new SessionAttribute(session, "swift-data", swiftData);
            genericDaoSupport.save(swiftAttr);
        } else {
            genericDaoSupport.update(swiftAttr.edit(swiftData));
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#pplFinalReport(com.ihg.hiex.entity.session.SessionReport, java.lang.String)
     */
    public void pplFinalReport(SessionReport sessionReport, String pplReport) {
        genericDaoSupport.update(sessionReport.editReport(pplReport, "assessorFinalReport"));
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#managerFinalReport(com.ihg.hiex.entity.session.SessionReport, java.lang.String)
     */
    public void managerFinalReport(SessionReport sessionReport, String managerReport) {
        genericDaoSupport.update(sessionReport.editReport(managerReport, "coachFinalReport"));
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#delegateFinalReport(com.ihg.hiex.entity.session.SessionReport, java.lang.String)
     */
    public void delegateFinalReport(SessionReport sessionReport, String delegateReport) {
        genericDaoSupport.update(sessionReport.editReport(delegateReport, "delegateFinalReport"));
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#batchPplFinalReport(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void batchPplFinalReport(List<SessionReport> sessionReports) {
        List<Long> ids = CollectionUtils.extractPropertyList(sessionReports, "id");
        sessionReportDao.updatePplReport(ReportGenerateStatus.GENERATING, ids);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#batchManagerFinalReport(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void batchManagerFinalReport(List<SessionReport> sessionReports) {
        List<Long> ids = CollectionUtils.extractPropertyList(sessionReports, "id");
        sessionReportDao.updateManagerReport(ReportGenerateStatus.GENERATING, ids);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#batchDelegateFinalReport(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void batchDelegateFinalReport(List<SessionReport> sessionReports) {
        List<Long> ids = CollectionUtils.extractPropertyList(sessionReports, "id");
        sessionReportDao.updateDelegateReport(ReportGenerateStatus.GENERATING, ids);
    }

    /* (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#sendDelegateReport(com.ihg.hiex.entity.session.after.SessionReport)
     */
    public void sendDelegateReport(SessionReport sessionReport) {
        genericDaoSupport.update(sessionReport.sendReport("delegateFinalReport"));
    }
    
    /* (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#sendManageReport(com.ihg.hiex.entity.session.after.SessionReport)
     */
    public void sendManagerReport(SessionReport sessionReport) {
        genericDaoSupport.update(sessionReport.sendReport("managerFinalReport"));
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#batchSendDelegateReport(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void batchSendDelegateReport(List<SessionReport> sessionReports) {
        List<Long> ids = CollectionUtils.extractPropertyList(sessionReports, "id");
        sessionReportDao.updateSendDelegateReport(ReportSendStatus.SENDING, ids);
    }
    
    /*
     * (non-Javadoc)
     * @see com.ihg.hiex.admin.service.session.SessionReportService#batchSendManagerReport(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void batchSendManagerReport(List<SessionReport> sessionReports) {
        List<Long> ids = CollectionUtils.extractPropertyList(sessionReports, "id");
        sessionReportDao.updateSendManagerReport(ReportSendStatus.SENDING, ids);
    }
    
}
